﻿using System;
using System.Diagnostics;
using UIExceptionHandler.Components;
using UIExceptionHandler.Interfaces;

namespace UIExceptionHandler.Controllers
{
    public class ErrorHandlerController
    {

        private readonly Exception _exception;
        private readonly IErrorHandlerForm _view;

        private bool _isDetailShow;

        public ErrorHandlerController(Exception exception, IErrorHandlerForm errorHandlerForm)
        {
            _view = errorHandlerForm;
            _exception = exception;
            SubscribeEvents();
        }

        private void SubscribeEvents()
        {
            _view.OnSendButtonClick += View_OnSendButtonClick;
            _view.OnShowErrorLinkClick += View_OnShowErrorLink;
            _view.OnLogFileLinkClick += View_OnLogFileLinkClick;
            _view.OnDebugButtonClick += View_OnDebugButtonClick;
        }

        private void View_OnSendButtonClick()
        {
            try
            {
                string bodyString = string.Format("Additional information: {0} \n Error: {1} \n Reply Email: {2}",
                                              _view.ExceptionDetailText,
                                              _view.ExceptionInfoText,
                                              _view.ReplyEmail);

                MailSender.SendEmail(Settings.ProgrammerEmail, string.Empty, Settings.FromEmail, bodyString, Settings.ExceptionSubject);
                _view.ShowInfoMessageBox("Email sended!", "Email..");
            }
            catch (Exception exception)
            {
                LogHelper.Logger.Error(exception);
                _view.ShowInfoMessageBox(
                    "Error, impossible to send a error to the developer. \n " +
                    "Please send the log file to the developer's email. " + Settings.ProgrammerEmail + "\n" +
                    "Log File:" + Environment.CurrentDirectory + " \n \n" + exception, "Error...");

                if (_view.ShowQuestionDialog("Attach debugger? \n Only for developer!!!", "Debugging..."))
                {
                    Debugger.Launch();
                    throw;
                }
            }
        }

        private void View_OnShowErrorLink()
        {
            _isDetailShow = !_isDetailShow;
            ShowDetailInfoException(_isDetailShow);
        }

        private void View_OnDebugButtonClick()
        {
            if (_view.ShowQuestionDialog("Attach debugger? \n Only for developer!!!", "Debugging..."))
            {
                Debugger.Launch();
                throw _exception;
            }
        }

        private void View_OnLogFileLinkClick()
        {
            Process.Start(Environment.CurrentDirectory);
        }

        private void ShowDetailInfoException(bool isShow)
        {
            const int minimazedHeight = 256;
            const int maximazedHeight = 515;

            _view.SetHeight(isShow
                               ? maximazedHeight
                               : minimazedHeight);
            _view.ShowExceptionInfoTextBox(isShow);

        }

        public void Run()
        {
            ShowDetailInfoException(_isDetailShow);

            string exceptionInfoText = string.Format(
                "An unexpected error occurred: {0}" + Environment.NewLine +
                "Time: {1} " + Environment.NewLine +
                "{2}" + Environment.NewLine +
                "InnerException: \n {3}" + Environment.NewLine +
                "InnerException StackTrace: \n  {4}" + Environment.NewLine,
                _exception.Message,
                DateTime.Now,
                _exception,
                _exception.InnerException,
                _exception.InnerException != null
                    ? _exception.InnerException.StackTrace
                    : string.Empty
            );

            LogHelper.Logger.Error(exceptionInfoText);
            _view.ExceptionInfoText = exceptionInfoText;
            _view.UpdateContactEmail(Settings.ProgrammerEmail);
            _view.ShowViewDialog();
        }
    }
}
